package ca.etsmtl.log320lab1;

import java.io.EOFException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectInputStream;

public class Decode {
	ObjectInputStream _fileReader;
	FileWriter _fileWriter;
	String[] _encryptionTable;
	char _currentChar;
	public Decode(ObjectInputStream fileReader, FileWriter fileWriter){
		_fileReader = fileReader;
		_fileWriter = fileWriter;
	}
	private void getEncryptionTable() throws ClassNotFoundException, IOException
	{
		int[] frequencyTable = new int[256];
		Boolean readDecodeInformation = true;
		int character = 0;
	    int frequency = 0;
		while (readDecodeInformation) {
			character = _fileReader.read();
			if (character == -1 || character > 256)
				return;
			frequency = _fileReader.read();
			if (character == 0 && frequency == 0) {
				break;
			}
			frequencyTable[character] = frequency;
		}
		Huffman huffman = new Huffman(frequencyTable);
		_encryptionTable = huffman.build();
	}
	public Boolean createDecodeFile() throws IOException, ClassNotFoundException
	{
		getEncryptionTable();
		if (_fileReader == null || _fileWriter == null ) {
			return false;
		}
		byte read;
		try {
			read = _fileReader.readByte();
		} catch (EOFException e) {
			read = -1;
		}
		String currentByte = "";
		while (read != -1) {
			for(int i = 7; i >= 0; i--) // pour chaque bit du byte
			{
				if(((read >>> i) & 0x1) == 0)
					currentByte += "0";
				else
					currentByte += "1";
				
				if (matchEncryptionTable(currentByte)) {
					_fileWriter.write(_currentChar);
					currentByte = "";
				}
			}	
			try {
				read = _fileReader.readByte();
			} catch (EOFException e) {
				read = -1;
			}
				
		}		
		_fileReader.close();
		_fileWriter.close();
		return true;
	}
	private Boolean matchEncryptionTable(String currentByte)
	{
		for (int i = 0; i < _encryptionTable.length; i++) {
			if(_encryptionTable[i] != null && _encryptionTable[i].equals(currentByte))
			{
				_currentChar = (char)i;
				return true;
			}		
		}
		return false;
	}
	
}
